package com.hrp.analyzer.util.compat

import android.util.Log
import org.slf4j.helpers.FormattingTuple
import org.slf4j.helpers.MessageFormatter

class PrintLog {

    companion object {
        @JvmField
        val log: PrintLog = PrintLog()

        var delegate: PrintLogDelegate? = null
    }

    fun verbose(message: String, vararg parameters: Any?) {
        delegate?.let {
            if (it.logLevel >= Log.VERBOSE) {
                val formattingTuple = formatMessage(message, parameters)
                it.verbose(formattingTuple.message, formattingTuple.throwable)
            }
        }
    }

    fun debug(message: String, vararg parameters: Any?) {
        delegate?.let {
            if (it.logLevel >= Log.DEBUG) {
                val formattingTuple = formatMessage(message, parameters)
                it.debug(formattingTuple.message, formattingTuple.throwable)
            }
        }
    }

    fun info(message: String, vararg parameters: Any?) {
        delegate?.let {
            if (it.logLevel >= Log.INFO) {
                val formattingTuple = formatMessage(message, parameters)
                it.info(formattingTuple.message, formattingTuple.throwable)
            }
        }
    }

    fun warn(message: String, vararg parameters: Any?) {
        delegate?.let {
            if (it.logLevel >= Log.WARN) {
                val formattingTuple = formatMessage(message, parameters)
                it.warn(formattingTuple.message, formattingTuple.throwable)
            }
        }
    }

    fun error(message: String, vararg parameters: Any?) {
        delegate?.let {
            if (it.logLevel >= Log.ERROR) {
                val formattingTuple = formatMessage(message, parameters)
                it.error(formattingTuple.message, formattingTuple.throwable)
            }
        }
    }

    fun assert(message: String, vararg parameters: Any?) {
        delegate?.let {
            if (it.logLevel >= Log.ASSERT) {
                val formattingTuple = formatMessage(message, parameters)
                it.assert(formattingTuple.message, formattingTuple.throwable)
            }
        }
    }


    private fun formatMessage(
        message: String,
        parameters: Array<out Any?>?,
    ): FormattingTuple {
        return MessageFormatter.arrayFormat(message, parameters)
    }

}


interface PrintLogDelegate {


    val logLevel: Int

    fun verbose(message: String, throwable: Throwable?)

    fun debug(message: String, throwable: Throwable?)

    fun info(message: String, throwable: Throwable?)

    fun warn(message: String, throwable: Throwable?)

    fun error(message: String, throwable: Throwable?)

    fun assert(message: String, throwable: Throwable?)

}

abstract class SimpleLogAdapter : PrintLogDelegate {

    override var logLevel: Int = Log.VERBOSE

    override fun verbose(message: String, throwable: Throwable?) {
        log(Log.VERBOSE, message, throwable)
    }

    override fun debug(message: String, throwable: Throwable?) {
        log(Log.DEBUG, message, throwable)
    }

    override fun info(message: String, throwable: Throwable?) {
        log(Log.INFO, message, throwable)
    }

    override fun warn(message: String, throwable: Throwable?) {
        log(Log.WARN, message, throwable)
    }

    override fun error(message: String, throwable: Throwable?) {
        log(Log.ERROR, message, throwable)
    }

    override fun assert(message: String, throwable: Throwable?) {
        log(Log.ASSERT, message, throwable)
    }

    abstract fun log(level: Int, message: String, throwable: Throwable?)


}




